home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Sample Code / Snippets / Toolbox / WDEFPatch 1.1 / wdefpatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  7.1 KB  |  349 lines  |  [TEXT/KAHL]

  1. /*******************************************
  2.  
  3.     WDEF Patcher
  4.     Steve Falkenburg MacDTS
  5.     ©1991 Apple Computer
  6.     
  7.     This snippet shows how you can add a simple extra part to a WDEF without
  8.     writing an entire WDEF.  It also shows how to access the new part via
  9.     FindWindow().
  10.  
  11.     6/1/92    SJF        fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up)
  12.     6/1/92    SJF        fixed varCode bug that made zoom boxes not work (masked out high 8 bits)
  13.     
  14. *******************************************/
  15.  
  16. #include <Windows.h>
  17.  
  18. /* add 2 to this when checking with FindWindow() ! */
  19.  
  20. #define kOurHit    32
  21.  
  22. Boolean gInBackground;
  23. Boolean gDone;
  24.  
  25. void InitStuff(void);
  26. void EventLoop(WindowPtr window);
  27. void DoDrag(WindowPtr window,Point globMouse);
  28. void HandleMouseDowns(EventRecord *ev);
  29. void HandleContent(WindowPtr theWindow,EventRecord *ev);
  30. void HandleUpdates(WindowPtr wind);
  31. void DoDeActivate(WindowPtr window,Boolean chFlag);
  32. void DoActivate(WindowPtr window,Boolean chFlag);
  33. void HandleActivates(EventRecord *ev);
  34. void HandleSREvt(long message);
  35. void DoGrow(WindowPtr window,Point globMouse);
  36. void PatchWindowWDEF(WindowPtr window);
  37. pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param);
  38. void HandleOurPart(WindowPtr window);
  39.  
  40.  
  41. /* this struct allows us to insert a WDEF patch safely.  It contains a jump instruction
  42.     and stores the old handle to the WDEF
  43. */
  44.  
  45. typedef struct {
  46.     short jmpInst;
  47.     ProcPtr patchAddr;
  48.     Handle oldAddr;
  49.     long ourA5;
  50. } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl;
  51.  
  52.  
  53. void main(void)
  54. {
  55.     WindowPtr mainWindow;
  56.     Rect bounds = {100,100,150,300};
  57.     
  58.     gInBackground = false;
  59.     gDone = false;
  60.     
  61.     InitStuff();
  62.     mainWindow = NewWindow(nil,&bounds,"\pWDEF Patcher",false,8,(WindowPtr)-1,true,0);
  63.     PatchWindowWDEF(mainWindow);
  64.     ShowWindow(mainWindow);
  65.     EventLoop(mainWindow);
  66. }
  67.  
  68.  
  69. void InitStuff(void)
  70. {
  71.     InitGraf(&qd.thePort);
  72.     InitFonts();
  73.     InitWindows();
  74.     InitMenus();
  75.     TEInit();
  76.     InitDialogs(nil);
  77.     InitCursor();
  78.     FlushEvents(everyEvent,0);
  79. }
  80.  
  81.  
  82. void EventLoop(WindowPtr window)
  83. {
  84.     EventRecord ev;
  85.     
  86.     do {
  87.         if (WaitNextEvent(everyEvent,&ev,10,nil)) {
  88.             switch (ev.what) {
  89.                 case mouseDown:
  90.                     HandleMouseDowns(&ev);
  91.                     break;
  92.                 case updateEvt:
  93.                     HandleUpdates((WindowPtr)ev.message);
  94.                     break;
  95.                 case activateEvt:
  96.                     HandleActivates(&ev);
  97.                     break;
  98.                 case app4Evt:
  99.                     HandleSREvt(ev.message);
  100.                     break;
  101.             }
  102.         }
  103.     } while (!gDone);
  104. }
  105.  
  106.  
  107. void HandleMouseDowns(EventRecord *ev)
  108. {
  109.     WindowPtr theWindow;
  110.     short part;
  111.     
  112.     part = FindWindow(ev->where,&theWindow);
  113.  
  114.     switch (FindWindow(ev->where,&theWindow)) {
  115.         case inMenuBar:
  116.             break;
  117.         case inSysWindow:
  118.             SystemClick(ev,theWindow);
  119.             break;
  120.         case inDrag:
  121.             DoDrag(theWindow,ev->where);
  122.             break;
  123.         case inGoAway:
  124.             if (TrackGoAway(theWindow,ev->where)) {
  125.                 gDone = true;
  126.             }
  127.             break;
  128.         case inContent:
  129.             HandleContent(theWindow,ev);
  130.             break;
  131.         case inGrow:
  132.             DoGrow(theWindow,ev->where);
  133.             break;
  134.         case kOurHit+2:                        // remember, we're adding 2 so the FindWindow/WDEF
  135.             HandleOurPart(theWindow);        // codes match
  136.             break;
  137.     }
  138. }
  139.  
  140.  
  141.  
  142. /* handles a mouse down in our added window part */
  143.  
  144. void HandleOurPart(WindowPtr window)
  145. {
  146.     long final;
  147.     
  148.     SetPort(window);
  149.     InvertRect(&window->portRect);
  150.     while (StillDown());
  151.     InvertRect(&window->portRect);
  152. }
  153.  
  154.  
  155. /* DoDrag: Handles drag window events */
  156.  
  157. void DoDrag(WindowPtr window,Point globMouse)
  158. {
  159.     Rect dragRect;
  160.     
  161.     SetRect(&dragRect,-32000,-32000,32000,32000);
  162.     
  163.     DragWindow(window,globMouse,&dragRect);
  164.     SetPort(window);
  165. }
  166.  
  167.  
  168. /* DoGrow: Handles grow window events */
  169.  
  170. void DoGrow(WindowPtr window,Point globMouse)
  171. {
  172.     long newSize;
  173.     Rect windLimits;
  174.     GrafPtr tempPort;
  175.     
  176.     SetRect(&windLimits,64,64,32000,32000);
  177.     
  178.     if ((newSize = GrowWindow(window,globMouse,&windLimits)) != 0) {
  179.         GetPort(&tempPort);
  180.         SetPort(window);
  181.         SizeWindow(window,LoWord(newSize),HiWord(newSize),true);
  182.         InvalRect(&window->portRect);
  183.         SetPort(tempPort);
  184.     }
  185. }
  186.  
  187.  
  188. void HandleContent(WindowPtr theWindow,EventRecord *ev)
  189. {
  190.     GrafPtr savePort;
  191.     Point where;
  192.     
  193.     where = ev->where;
  194.     SetPort(theWindow);
  195.     
  196.     if (theWindow != FrontWindow()) {
  197.         SelectWindow(theWindow);
  198.         return;
  199.     }
  200. }
  201.  
  202.  
  203. void HandleUpdates(WindowPtr wind)
  204. {
  205.     GrafPtr savePort;
  206.     
  207.     GetPort(&savePort);
  208.     SetPort(wind);
  209.     BeginUpdate(wind);
  210.     EraseRect(&wind->portRect);
  211.     DrawGrowIcon(wind);
  212.     EndUpdate(wind);
  213.     SetPort(savePort);
  214. }
  215.  
  216.  
  217. void HandleActivates(EventRecord *ev)
  218. {
  219.     if ((ev->modifiers & activeFlag) != 0) {
  220.         DoActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
  221.     }
  222.     else {
  223.         DoDeActivate((WindowPtr)ev->message,((ev->modifiers & 0x0002) != 0));
  224.     }
  225. }
  226.  
  227.  
  228. /* DoActivate: Performs activate tasks */
  229.  
  230. void DoActivate(WindowPtr window,Boolean chFlag)
  231. {
  232.     DrawGrowIcon(window);
  233. }
  234.  
  235.  
  236. /* DoDeActivate: Performs deactivate tasks */
  237.  
  238. void DoDeActivate(WindowPtr window,Boolean chFlag)
  239. {
  240.     DrawGrowIcon(window);
  241. }
  242.  
  243.  
  244. void HandleSREvt(long message)
  245. {
  246.     if ((message >> 24) == 1)
  247.         if ((message & 1) != 0) {
  248.             gInBackground = false;
  249.             SetCursor(&arrow);
  250.             if (FrontWindow()) {  
  251.                 HiliteWindow(FrontWindow(),true);
  252.                 DoActivate(FrontWindow(),true);
  253.             }
  254.         }
  255.         else if (FrontWindow()) {
  256.             gInBackground = true;
  257.             HiliteWindow(FrontWindow(),false);
  258.             DoDeActivate(FrontWindow(),true);
  259.         }
  260. }
  261.  
  262.  
  263.  
  264.  
  265. /* this installs the WDEF patch into a window */
  266.  
  267. void PatchWindowWDEF(WindowPtr window)
  268. {
  269.     WDEFPatchHndl wdefHndl;
  270.     WDEFPatchPtr wdefPatch;
  271.     Handle oldAddr;
  272.     unsigned long wdefEntry;
  273.     
  274.     wdefHndl = (WDEFPatchHndl)NewHandle(sizeof(WDEFPatch));
  275.     if (MemError()!=noErr)
  276.         ExitToShell();
  277.         
  278.     oldAddr = ((WindowPeek)window)->windowDefProc;
  279.     if (GetMMUMode()) // 32-bit
  280.         wdefEntry = (unsigned long)wdefHndl;
  281.     else
  282.         wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000);
  283.     
  284.     HLock(wdefHndl);
  285.     wdefPatch = *wdefHndl;
  286.     wdefPatch->oldAddr = oldAddr;
  287.     wdefPatch->jmpInst = 0x4ef9; /*JMP*/
  288.     wdefPatch->patchAddr = MyWDEFPatch;
  289. #ifdef __SYSEQU__
  290.     wdefPatch->ourA5 = *(long *)CurrentA5;
  291. #else
  292.     wdefPatch->ourA5 = (long)CurrentA5;
  293. #endif
  294.     HUnlock(wdefHndl);
  295.     ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry;
  296. }
  297.  
  298.  
  299. pascal long MyWDEFPatch(short varCode,WindowPtr window,short message,long param)
  300. {
  301.     WDEFPatchHndl wdPatch;
  302.     pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param);
  303.     Handle oldWDEF;
  304.     long result;
  305.     Rect ourRect,ourElementRect;
  306.     Point *hitPt;
  307.     Point mouse;
  308.     long appA5,saveA5;
  309.     
  310.     wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc;
  311.     appA5 = (**wdPatch).ourA5;
  312.     saveA5 = SetA5(appA5);
  313.     
  314.     ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox;
  315.     SetRect(&ourElementRect,ourRect.right-32,ourRect.top+4,ourRect.right-20,ourRect.top+15);
  316.     
  317.     oldWDEF = (**wdPatch).oldAddr;
  318.     HLock(oldWDEF);
  319.     wdefProc = (void *)*oldWDEF;
  320.     wdefProc = (void *)StripAddress(wdefProc);
  321.     result = (wdefProc)(varCode,window,message,param);
  322.     
  323.     switch (message) {
  324.         case wDraw:
  325.             if (((WindowPeek)window)->visible) {
  326.                 PenNormal();                            // draw our part
  327.                 InsetRect(&ourElementRect,-1,0);
  328.                 EraseRect(&ourElementRect);
  329.                 InsetRect(&ourElementRect,1,0);
  330.                 FrameRect(&ourElementRect);
  331.                 InsetRect(&ourElementRect,2,2);
  332.                 FrameRect(&ourElementRect);
  333.             }
  334.             break;
  335.         case wHit:
  336.             hitPt = (Point *)¶m;                    // hit test our part
  337.             if (PtInRect(*hitPt,&ourElementRect))
  338.                 result =  kOurHit;
  339.             break;
  340.     }
  341.  
  342.     HUnlock(oldWDEF);
  343.     
  344.     SetA5(saveA5);
  345.     
  346.     return result;
  347. }
  348.  
  349.